import { DirUtil } from "./DirUtil";
import { Md5Util } from "./Md5Util";
import { FileIoUtil } from "./FileIOUtil";
import { Main } from "../Main";
import { SyncResInfoUtil } from "./SyncResInfoUtil";
import { SyncResExecUtil } from "./SyncResExecUtil";

/**
 * 文件改变检测工具
 * @author 赵占涛
 */
export class FileChangeUtil {
    private static get cachePath() {
        return Main.codePath + "Resources/Md5Cache.json";
    }
    /**
     * 得到所有文件的md5
     */
    private static getAllFileMd5(path: string, cb: (fileMd5: { [key: string]: string }) => void, signOtherCalc: (file: string) => string) {
        let allFile = DirUtil.getAllFile(path);
        let allMd5: { [key: string]: string } = {};
        let count = 0;
        if (allFile.length > 0) {
            for (let i = 0; i < allFile.length; i++) {
                const one = allFile[i];
                Md5Util.fileMd5(path + one, (md5: string) => {
                    let otherSign = signOtherCalc(one);
                    allMd5[one] = md5 + "|" + otherSign;
                    count++;
                    if (count == allFile.length) {
                        cb(allMd5);
                    }
                });
            }
        } else {
            cb(allMd5);
        }
    }
    /**
     * 保存该文件夹下所有文件的签名信息（文件md5）
     * @param path 文件夹路径
     * @param cb 完成回调
     */
    static saveFileSign(path: string, cb: () => void, signOtherCalc: (file: string) => string) {
        let parentName = this.getParentName(path);
        this.getAllFileMd5(path, (fileMd5) => {
            FileIoUtil.readFile(this.cachePath, (data) => {
                let md5cache = JSON.parse(data.toString());
                md5cache[parentName] = {};
                for (const key in fileMd5) {
                    if (fileMd5.hasOwnProperty(key)) {
                        md5cache[parentName][key] = fileMd5[key];
                    }
                }
                FileIoUtil.writeFile(this.cachePath, JSON.stringify(md5cache, undefined, 4), () => {
                    cb();
                })
            })
        }, signOtherCalc);
    }
    /**
     * 获取父节点名
     * @param path 路径
     */
    private static getParentName(path: string) {
        return path.substr(Main.codePath.length);
    }
    /** 
     * 找到变更的文件(变更的，新增的，删除的)
     */
    static changed(path: string, cb: (fileChange: string[], fileAdd: string[], fileDelete: string[]) => void, signOtherCalc: (file: string) => string) {
        let parentName = this.getParentName(path);
        this.getAllFileMd5(path, (fileMd5) => {
            FileIoUtil.readFile(this.cachePath, (data) => {
                let md5cache = JSON.parse(data.toString());
                if (!md5cache[parentName]) {
                    md5cache[parentName] = {};
                }
                let old = md5cache[parentName];
                let dtChange: { [key: string]: true } = {};
                let dtAdd: { [key: string]: true } = {};
                let dtDelete: { [key: string]: true } = {};
                for (const key in old) {
                    if (old.hasOwnProperty(key)) {
                        if (old[key] != fileMd5[key]) {
                            if (fileMd5[key]) {
                                dtChange[key] = true;
                            } else {
                                dtDelete[key] = true;
                            }
                        }
                    }
                }
                for (const key in fileMd5) {
                    if (fileMd5.hasOwnProperty(key)) {
                        if (fileMd5[key] != old[key]) {
                            if (old[key]) {
                                dtChange[key] = true;
                            } else {
                                dtAdd[key] = true;
                            }
                        }
                    }
                }
                cb(Object.keys(dtChange), Object.keys(dtAdd), Object.keys(dtDelete));
            });
        }, signOtherCalc);
    }
}